#include "qqtcrashreport.h"

#ifdef __MSVC__

#include <windows.h>
#include <dbghelp.h>

LONG ApplicationCrashHandler ( EXCEPTION_POINTERS* pException ) //程式异常捕获
{
    /*
      ***保存数据代码***
    */
    //创建 Dump 文件
    HANDLE hDumpFile = CreateFile ( QTime::currentTime().toString ( "%1_HH时mm分ss秒zzz.dmp" ).arg ( QString (
                                        __FILE__ ).split ( '/' ).last() ).toStdWString().data(), GENERIC_WRITE, 0,
                                    NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
    if ( hDumpFile != INVALID_HANDLE_VALUE )
    {
        //Dump信息
        MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
        dumpInfo.ExceptionPointers = pException;
        dumpInfo.ThreadId = GetCurrentThreadId();
        dumpInfo.ClientPointers = TRUE;
        //写入Dump文件内容
        MiniDumpWriteDump ( GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL );
    }
    //这里弹出一个错误对话框并退出程序
    EXCEPTION_RECORD* record = pException->ExceptionRecord;
    QString errCode ( QString::number ( record->ExceptionCode, 16 ) ),
            errAdr ( QString::number ( ( uint ) record->ExceptionAddress, 16 ) ), errMod;
    QMessageBox::critical ( NULL, "程式崩溃",
                            "<FONT size=4><div><b>对于发生的错误，表示诚挚的歉意</b><br/></div>" +
                            QString ( "<div>错误代码：%1</div><div>错误地址：%2</div></FONT>" ).arg ( errCode ).arg ( errAdr ),
                            QMessageBox::Ok );
    return EXCEPTION_EXECUTE_HANDLER;
}

#elif 0

void SigSegv_handler ( int signo )
{
    int j, nptrs;
    void* buffer[BT_BUF_SIZE];
    char** strings;

    nptrs = backtrace ( buffer, BT_BUF_SIZE );
    printf ( "backtrace() returned %d addresses\n", nptrs );

    /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
       would produce similar output to the following: */

    strings = backtrace_symbols ( buffer, nptrs );
    if ( strings == NULL )
    {
        perror ( "backtrace_symbols" );
        exit ( EXIT_FAILURE );
    }

    for ( j = 0; j < nptrs; j++ )
        printf ( "%s\n", strings[j] );

    free ( strings );
    　　　　　　 exit ( -1 );
}

#endif

QQtCrashReport* QQtCrashReport::_instance = 0;

QQtCrashReport::~QQtCrashReport()
{

}

QQtCrashReport::QQtCrashReport ( QObject* parent ) : QObject ( parent )
{
#ifdef __MSVC__
    SetUnhandledExceptionFilter ( ( LPTOP_LEVEL_EXCEPTION_FILTER ) ApplicationCrashHandler );
#endif
}
